#include <stdint.h>
#include <string.h>

static void tea_decrypt(uint32_t *v, uint32_t *k)
{
    uint32_t y = v[0], z = v[1], sum = 0xC6EF3720, i; /* set up */
    uint32_t delta = 0x9e3779b9;                      /* a key schedule constant */
    uint32_t a = k[0], b = k[1], c = k[2], d = k[3];  /* cache key */
    for (i = 0; i < 32; i++)
    { /* basic cycle start */
        z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
        y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
        sum -= delta; /* end cycle */
    }
    v[0] = y;
    v[1] = z;
}

int nb_bin_decrypt_chunk(uint8_t *chunk, int chunksz, int *global_pos, uint8_t *previous, uint8_t *key)
{
    uint8_t current[8];
    uint8_t ckey[16];
    int inside_pos;
    uint8_t inside_chunk[8];

    if (chunksz % 8 != 0)
    {
        return -1;
    }

    memset(current, 0, 8);
    memcpy(ckey, key, 16);

    for (int i = 0; i < (*global_pos >> 10); i++)
    {

        for (int j = 0; j < 16; j++)
            ckey[j] += j;
    }
    inside_pos = *global_pos & 0x000003FF;
    for (int i = 0; i < chunksz; i += 8, *global_pos += 8, inside_pos += 8)
    {
        memcpy(current, &chunk[i], 8);

        if ((inside_pos & 0x000003FF) == 0 && inside_pos != 0)
        {
            for (int j = 0; j < 16; j++)
                ckey[j] += j;
        }
        memcpy(inside_chunk, chunk + i, 8);
        tea_decrypt((uint32_t *)(inside_chunk), (uint32_t *)ckey);
        memcpy(chunk + i, inside_chunk, 8);
        if (*global_pos != 0)
        {
            for (int j = 0; j < 8; j++)
            {
                chunk[i + j] = chunk[i + j] ^ previous[j];
            }
        }
        memcpy(previous, current, 8);
    }

    return 0;
}
